package cn.keniykey.mc.landterritory.landflag.flag;

import java.util.Arrays;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;

import cn.keniykey.mc.landterritory.config.ConfigurationManager;
import cn.keniykey.mc.landterritory.config.LanguageManager;
import cn.keniykey.mc.landterritory.event.LandTerritoryReloadConfigEvent;
import cn.keniykey.mc.landterritory.land.api.ILandManager;
import cn.keniykey.mc.landterritory.land.api.Land;
import cn.keniykey.mc.landterritory.land.api.LandUtil;
import cn.keniykey.mc.landterritory.land.api.LandUtil.ELandPermissionLevel;
import cn.keniykey.mc.landterritory.landflag.api.ELandFlagParType;
import cn.keniykey.mc.landterritory.landflag.api.ELandFlagType;
import cn.keniykey.mc.landterritory.landflag.api.ILandFlagDetection;
import cn.keniykey.mc.landterritory.landflag.api.JavaLandFlag;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagConfigurationFile;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagListenerManager;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagSetting;
import cn.keniykey.mc.landterritory.toolkit.Util;
import cn.keniykey.mc.landterritory.vault.Perm;

public final class ProtectBuildFlag extends JavaLandFlag implements Listener,ILandFlagDetection{
	private String tip,per_add;
	private ELandFlagType type;
	
	@Override
	public ELandFlagParType getELandFlagParType() {
		return ELandFlagParType.NONE;
	}
	@Override
	public ELandFlagType getELandFlagType() {
		return this.type;
	}
	@Override
	public boolean allowAllPlayerData() {
		return false;
	}
	
	@Override
	public void onEnable() {
		LandFlagListenerManager.registerListener(this, this);
		LandFlagSetting.setAddDetection(this, this);
	}
	
	@EventHandler
	public void onConfigLoad(final LandTerritoryReloadConfigEvent e) {
		final LandFlagConfigurationFile config = this.getLandFlagConfigurationFile();
		if(!config.has()) {
			config.set("name", "建筑保护");
			config.set("lore", Arrays.asList("&7（禁止玩家在领地内放置、破坏方块以及倒装液体）"));
			config.set("tip", "&c领地标记限制，不可以放置/破坏方块/倒装液体");
			config.set("per", "land.flag." + this.getName());
		}
		this.setDisplayName(Util.conver(config.getString("name")));
		this.setIntroductionLore(Util.conver(config.getStringList("lore")));
		this.tip = LanguageManager.getChatPrefix() + Util.conver(config.getString("tip"));
		this.per_add = config.getString("per");
		if(this.per_add == null || this.per_add.isEmpty()) {
			this.type = ELandFlagType.PLAYER;
		}else if(this.per_add.equals(ConfigurationManager.AdminPer)) {
			this.type = ELandFlagType.ADMIN;
		}else {
			this.type = ELandFlagType.SPECIAL;
		}
	}
	
	private void onCancellable(final Player player,final Location loc,final Cancellable able) {
		final Land land = ILandManager.getILandManager().getHighestPriorityLand(loc);
		if(land == null) return;
		if(!JavaLandFlag.hasLandFlag(land, this)) return;
		able.setCancelled(true);
		player.sendMessage(this.tip);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onBlockBreakEvent(final BlockBreakEvent e) {
		this.onCancellable(e.getPlayer(), e.getBlock().getLocation(), e);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onHangingBreakByEntity(final HangingBreakByEntityEvent e) {
		if (e.getRemover() == null || !(e.getRemover() instanceof Player)) return;
		this.onCancellable((Player)e.getRemover(), e.getEntity().getLocation(), e);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onBlockPlace(final BlockPlaceEvent e) {
		this.onCancellable(e.getPlayer(), e.getBlock().getLocation(), e);
		if(e.isCancelled()) e.setBuild(false);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onHangingPlace(final HangingPlaceEvent e) {
		final Player player = e.getPlayer();
		if(player == null) return;
		this.onCancellable(player, e.getEntity().getLocation(), e);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onBlockCanBuild(final BlockCanBuildEvent e) {
		final Player player = e.getPlayer();
		if(player == null) return;
		final Land land = ILandManager.getILandManager().getHighestPriorityLand(e.getBlock().getLocation());
		if(land == null) return;
		if(!JavaLandFlag.hasLandFlag(land, this)) return;
		e.setBuildable(false);
		player.sendMessage(this.tip);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onPlayerBucketEmpty(final PlayerBucketEmptyEvent e) {
		this.onCancellable(e.getPlayer(), e.getBlock().getLocation(), e);
	}
	@EventHandler(priority = EventPriority.LOW,ignoreCancelled = true)
	public void onPlayerBucketFill(final PlayerBucketFillEvent e) {
		this.onCancellable(e.getPlayer(), e.getBlock().getLocation(), e);
	}
	@Override
	public boolean onRequest(Player player, Land land) {
		switch(this.type) {
		case PLAYER:
			return true;
		case ADMIN:
			return LandUtil.hasLandPermission(player, land, ELandPermissionLevel.ADMIN);
		default:
		}
		return Perm.getPerm().hasPermission(land.getWorldName(), player, this.per_add);
	}
}